<?php defined('SYSPATH') or die('No direct access allowed.');

class Model_Segment extends Model{
	
	public $samples = array();
	public $min = 0;
	public $max = 0;
	public $length = 0;
	
	
	//Construccion de un segmento a partir de un conjunto de datos separados por pipes en formato string
	public static function create($dataset){
		$segment = parent::factory("segment");
		$segment->unserialize($dataset);
		return $segment;
	}
		
	/*
	 *  Calcula la media aritmetica entre las muestras del segmento 
	 */
	public function avg(){
		$this->length = count($this->samples); 
		if ($this->length <= 0) return 0;
		
		for($i = 0, $sum = 0; $i < $this->length; $i++){
			$sum += $this->samples[$i];
		} 
		
		return $sum / $this->length;
		
	}
	
	/*
	 * 	Calcula el numero de muestras del segmento, el valor minimo y el valor maximo
	 */
	public function calculateEdges(){
		$this->length = count($this->samples);
			
		for ($i=0; $i < $this->length; $i++){
			$sample = $this->samples[$i];
			
			if ($i > 0){
				if ($sample < $this->min) $this->min = $sample;
				if ($sample > $this->max) $this->max = $sample;
			}else{
				$this->min = $sample; //calculo el valor minimo de la señal
				$this->max = $sample; //calculo el valor maximo de la señal
			}
		
		}
	}
	
	public function getSamples($precision=5){
		$prec_samples = array();
		for ($i = 0; $i < $this->length; $i++){
			$prec_samples[$i] = round(floatval($this->samples[$i]),$precision);
		}
		return $prec_samples;
	}
	
	
	/*
	 * Verifica que el segmento este normalizado
	 */
	public function isNormalized(){
		if (count($this->samples) == 0) return;
		$sample = intval($this->samples[0]); //podria tirar una excepcion de numero mal formado? is a number? 
				
		if ($sample <= 5 && $sample >= 0) return true;
		return false;
	}
	
	/*
	 * Normaliza entre 0 y 3 los valores del segmento
	 */
	public function normalize(){
		//dividir todas las muestras por 100 o por 10?
	}
	
	
	/*
	 * Serializa el segmento para almacenarse en la base de datos separando las muestras entre pipes "|"
	 * Remueve espacios en blanco, caracteres de fin de carro y nueva linea
	 */
	public function serialize(){
		$serialized = implode("|",$this->samples);
		$serialized = str_replace(" ","",$serialized);
		$serialized = str_replace("\r","",$serialized);
		$serialized = str_replace("\n","",$serialized);
		return $serialized; // Remuevo caracteres en blanco, fin de carro y nueva linea
		
	}
	
	/*
	 * Setea las muestras del segmento y calcula los extremos
	 */
	public function setSamples(array $samples){
		$this->samples = $samples;
		$this->calculateEdges();
		return;
	}
	
	/*
	 * Representacion grafica en una imagen del segmento
	 * $settings type chartsettings (array de configuracion para la creacion del chart)
	 */
	public function toChart($legend, $series_name, $thumbnail=false,$settings=false, $toFile=false){
		
		if ($settings == false){
			$settings = Model::factory("chartsettings");
			$settings->seriesName = $series_name;
			$settings->dataLabelSkip = 40;
			$settings->YAxisLabel = "Amplitud [%]";
			$settings->XAxisLabel = "Tiempo [ms]";
			$settings->setSeriesColor(55,91,127);
			$settings->setAxisBoundaries(0,100);
			$settings->chartHeight = ($thumbnail)? 150 : 300;
			$settings->chartWidth = ($thumbnail) ? 150 : 300;
			$settings->chartTitle = $legend;
		}
		$precision = 3;
		$chart = Model::factory("chart");			
		$chart->create($this->getSamples($precision),$settings);
		if ($toFile){
			$chart->render($toFile);
		}else{
			$chart->stream();	
		}
		
	}
	
	
	/*
	 * Representacion JSON del segmento
	 */
	public function toJSON($factor = 1){
		//el factor es para pasar de muestras a milisegundos -->cambio de unidad
		$reply = '{';
		$reply.= '"minimo":"'.$this->min.'",';
		$reply.= '"maximo":"'.$this->max.'",';
		$reply.= '"nsamples":"'.$this->length*$factor.'",';
		
		$reply.= '"data":[';
	
		foreach($this->samples as $x=>$y){
			$reply.='["'.$x*$factor.'","'.round($y,5).'"],'; //especifico la precision decimal hasta 5 digitos
		}
	
		$reply = substr($reply,0,-1);
		$reply.=']}';

		return $reply;
	}
	
	public function toFile($filenamepath){
		$contenido = implode("\r\n",$this->getSamples()); 			
		$f=fopen($filenamepath,"w");
		fwrite($f,$contenido);
		fclose($f);
	}
	
	
	/*
	 * Construye un objeto segmento a partir de las muestras serializadas
	 */
	public function unserialize($str_samples){
		$this->samples = explode("|",$str_samples);
		$this->calculateEdges();
		return;		
	}
	
	
	
}
//End of Segment ?>